#include "net.h"
#include "node.h"

namespace ann
{
    /*virtual*/ net::~net(void) 
    {
        for( npVec::iterator itr = m_nodes.begin(); itr != m_nodes.end(); ++itr )
        {
            SAFE_DEL(*itr);
        }
        for( trVec::iterator itr = m_trData.begin(); itr != m_trData.end(); ++itr )
        {
            if ( *itr != NULL)
            {
                (*itr)->m_inVec.clear();
                (*itr)->m_outVec.clear();
                delete *itr;
                (*itr) = NULL;
            }
        }
        m_lStruct.clear();
        m_nodes.clear();
        m_trData.clear();
    }

    /*virtual*/ const UINT net::LoadTRDataFromFile(const wchar_t* ptrDataFilePath)
    {
        assert( ptrDataFilePath != NULL );

        std::ifstream inf( ptrDataFilePath, std::ifstream::in );
        if ( !inf.is_open() )
        {
            DEBUG("error: can't open train data file.");
            m_status |= eann_FOTRDataFile;
            return m_status;
        }

        UINT cnt = 0;
        UINT inCnt = 0;
        UINT outCnt = 0;
        inf>>cnt>>inCnt>>outCnt;

        if ( cnt<1 || inCnt<1 || inCnt>m_inCnt || outCnt<1 || outCnt>m_outCnt )
        {
            DEBUG("error: train data file reading error, maybe a wrong file format.");
            m_status |= eann_FETRDataFile;
            return m_status;
        }

        double tVal = 0.0;
        for( UINT i = 0; i < cnt; ++i )
        {
            TRData* trData = new TRData();
            trData->m_ek = 1.0;
            for( UINT j = 0; j < m_inCnt; ++j )
            {
                inf>>tVal;
                trData->m_inVec.push_back(tVal);
            }
            for( UINT j = 0; j < m_outCnt; ++j )
            {
                inf>>tVal;
                trData->m_outVec.push_back(tVal);
            }
            m_trData.push_back(trData);
        }

        return m_status;
    }

    /*virtual*/ const double net::CalEk(const dVec& pObjVec)
    {
        assert( pObjVec.size() == m_outCnt );

        double tSum = 0.0;
        double tVal = 0.0;
        const UINT ll = m_lStruct.size() - 1;

        for( UINT i = 0; i < m_outCnt; ++i )
        {
            tVal = m_nodes[GetNodeIdx(ll,i)]->Get_m_data() - pObjVec[i];
            tSum += tVal*tVal;
        }

        return 0.5*tSum;
    }

}
